/*
 * InvulgoTracker
 * Copyright (C) Thomas Andersen 2011 <thomas.1.andersen@gmail.com>
 * 
 * InvulgoTracker is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * InvulgoTracker is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "task-time.h"


TaskTime::TaskTime()
{
    time_t rawtime;
    struct tm *ti;
    
    time ( &rawtime );
    ti = localtime ( &rawtime );
    this->timeInfo = *ti;
}

TaskTime::TaskTime(const char *str)
{
    time_t rawtime;
    struct tm *ti;

    time ( &rawtime );
    ti = localtime ( &rawtime );
    this->timeInfo = *ti;
    TimeFromStringNoCheck(str);
}

TaskTime::TaskTime(int year, int month, int day)
{
    time_t rawtime;
    struct tm *ti;

    time ( &rawtime );
    ti = localtime ( &rawtime );
    ti->tm_year = year - 1900;
    ti->tm_mon = month - 1;
    ti->tm_mday = day;
    mktime(ti);
    this->timeInfo = *ti;
}


TaskTime::~TaskTime()
{
}


long TaskTime::Minutes()
{
    return long ((timeInfo.tm_hour*60)+timeInfo.tm_min);
}


char *TaskTime::TimeText()
{
    char *res = (char *)malloc(21);

    sprintf(res,"%.2d:%.2d", this->timeInfo.tm_hour,this->timeInfo.tm_min);

    return res;
}

char *TaskTime::DateText()
{
    char *res = (char *)malloc(51);

    sprintf(res, "%.4d-%.2d-%.2d", timeInfo.tm_year+1900, timeInfo.tm_mon+1, timeInfo.tm_mday);

    return res;
}


void TaskTime::TimeFromString(const char *str)
{
    char hours[21] = {0};
    char minutes[21] = {0};
    char *ch1, *ch2;
    int h,m;

    ch2 = NULL;
    if (strlen(str)>2) {
        ch1 = hours;
        ch2 = minutes;
    } else
        ch1 = minutes;

    while(ch1 && *str >= '0' && *str <= '9')
        *ch1++ = *str++;
    *ch1 = 0;
    if (*str)
        str++;
    while(ch2 && *str >= '0' && *str <= '9')
        *ch2++ = *str++;
    if (ch2)
        *ch2 = 0;

    h = atoi(hours);
    m = atoi(minutes);

    if (h>=100) {
        int tmp = h / 100;
        m = h - (tmp * 100);
        h = tmp;
    }

    if (h>23)
        h = 0;
    if (m>59)
        m = 0;
    timeInfo.tm_hour = h;
    timeInfo.tm_min = m;
}

void TaskTime::TimeFromStringNoCheck(const char *str)
{
    char hours[21] = {0};
    char minutes[21] = {0};
    char *ch1, *ch2;
    int h,m;

    ch2 = NULL;
    if (strlen(str)>2) {
        ch1 = hours;
        ch2 = minutes;
    } else
        ch1 = minutes;

    while(ch1 && *str >= '0' && *str <= '9')
        *ch1++ = *str++;
    *ch1 = 0;
    if (*str)
        str++;
    while(ch2 && *str >= '0' && *str <= '9')
        *ch2++ = *str++;
    *ch2 = 0;

    h = atoi(hours);
    m = atoi(minutes);

    timeInfo.tm_hour = h;
    timeInfo.tm_min = m;
}

int TaskTime::GetYear()
{
    return timeInfo.tm_year + 1900;
}

int TaskTime::GetMonth()
{
    return timeInfo.tm_mon;
}

int TaskTime::GetDay()
{
    return timeInfo.tm_mday;
}

int TaskTime::GetWeekDay()
{
    return timeInfo.tm_wday;
}

TaskTime TaskTime::AddTime(const TaskTime &t)
{
    TaskTime res = *this;

    res.timeInfo.tm_min += t.timeInfo.tm_min;
    while(res.timeInfo.tm_min>59) {
        res.timeInfo.tm_hour++;
        res.timeInfo.tm_min -= 60;
    }
    res.timeInfo.tm_hour += t.timeInfo.tm_hour;
    return res;
}

TaskTime TaskTime::SubTime(const TaskTime &t)
{
    TaskTime res = *this;

    if (res.timeInfo.tm_hour < t.timeInfo.tm_hour 
        || (res.timeInfo.tm_hour == t.timeInfo.tm_hour 
            && res.timeInfo.tm_min < t.timeInfo.tm_min))
        res.timeInfo.tm_hour += 24;
    res.timeInfo.tm_min -= t.timeInfo.tm_min;
    while(res.timeInfo.tm_min<0) {
        res.timeInfo.tm_hour--;
        res.timeInfo.tm_min += 60;
    }
    res.timeInfo.tm_hour -= t.timeInfo.tm_hour;
    return res;
}


TaskTime TaskTime::AddDay(int days)
{
    TaskTime res = *this;

    res.timeInfo.tm_mday += days;
    mktime(&res.timeInfo);

    return res;
}


bool TaskTime::operator<(const TaskTime &other) const
{
    long m1, m2;
    
    m1 = (long)(this->timeInfo.tm_hour * 60) + this->timeInfo.tm_min;
    m2 = (long)(other.timeInfo.tm_hour * 60) + other.timeInfo.tm_min;
    return m1 < m2;
}

bool TaskTime::operator>(const TaskTime &other) const
{
    long m1, m2;

    m1 = (long)(this->timeInfo.tm_hour * 60) + this->timeInfo.tm_min;
    m2 = (long)(other.timeInfo.tm_hour * 60) + other.timeInfo.tm_min;
    return m1 > m2;
}

bool TaskTime::operator==(const TaskTime &other) const
{
    long m1, m2;

    m1 = (long)(this->timeInfo.tm_hour * 60) + this->timeInfo.tm_min;
    m2 = (long)(other.timeInfo.tm_hour * 60) + other.timeInfo.tm_min;
    return m1 == m2;
}

